package com.fm.webrtc;

import android.Manifest;
import android.content.pm.PackageManager;
import android.os.Build;
import android.os.Bundle;
import android.util.Log;
import android.view.View;
import android.widget.ImageView;


import androidx.annotation.RequiresApi;
import androidx.appcompat.app.AppCompatActivity;
import androidx.core.app.ActivityCompat;
import androidx.core.content.ContextCompat;
import androidx.recyclerview.widget.GridLayoutManager;
import androidx.recyclerview.widget.RecyclerView;


import com.fm.mediasoup.callback.TrackCallback;
import com.fm.webrtc.adapter.VideoRecyclerAdapter;
import com.fm.mediasoup.callback.CallbackPeerMessage;
import com.fm.webrtc.message.MediaStreamMessage;
import com.fm.webrtc.modle.StreamModel;
import com.fm.webrtc.presenter.ProducerPresenter;
import com.fm.webrtc.view.ProducerView;
import com.fm.webrtc.websocket.message.callback.CallConnectMessage;
import com.fm.webrtc.websocket.controller.RequestController;

import org.webrtc.AudioTrack;
import org.webrtc.EglBase;
import org.webrtc.SurfaceTextureHelper;
import org.webrtc.SurfaceViewRenderer;
import org.webrtc.VideoTrack;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

public class MainActivity extends AppCompatActivity implements MediaStreamMessage, CallConnectMessage, View.OnClickListener, ProducerView, TrackCallback {

    private final static String TAG = MainActivity.class.getSimpleName();
    static {
        //   System.loadLibrary("jingle_peerconnection_so");
        System.loadLibrary("webrtc");
    }
    private SurfaceViewRenderer svrLocal;

    private RecyclerView videoRecyclerView;

    private StreamModel streamModel;

    private String peerId = "local";

    private ImageView videoCam;
    private ImageView mic;

    private SurfaceTextureHelper surfaceTextureHelper;

    private EglBase.Context eglBaseContext;

    private VideoRecyclerAdapter videoRecyclerAdapter;

    private RequestController requestController;

    private ProducerPresenter producerPresenter;

    public static native void  test();

    public static native void start(CallbackPeerMessage callbackPeerMessage);

    public static native void sendMessage(int peerId, String message);

    //需要申请两个权限，拍照和SD读写
    //1、首先声明一个数组permissions，将需要的权限都放在里面
    String[] permissions=new String[]{Manifest.permission.WRITE_EXTERNAL_STORAGE,
            Manifest.permission.READ_EXTERNAL_STORAGE, Manifest.permission.INTERNET,
            Manifest.permission.CAMERA, Manifest.permission.RECORD_AUDIO, Manifest.permission.ACCESS_NETWORK_STATE};
    //2、创建一个mPermissionList，逐个判断哪些权限未授予，未授予的权限存储到mPerrrmissionList中
    List<String> mPermissionlist=new ArrayList<>();

    //权限判断和申请
    private void initPermission(){
        mPermissionlist.clear();//清空没有通过的权限

        //逐个判断你要的权限是否已经通过
        for(int i=0;i<permissions.length;i++){
            if(ContextCompat.checkSelfPermission(this,permissions[i])!= PackageManager.PERMISSION_GRANTED){
                mPermissionlist.add(permissions[i]);//添加还未授予的权限
            }
        }

        //申请权限
        if(mPermissionlist.size()>0){//有权限没有通过，需要申请
            ActivityCompat.requestPermissions(this,permissions,6666);
        } else {

        }

    }


    @RequiresApi(api = Build.VERSION_CODES.O)
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        initPermission();
        streamModel = new StreamModel();
        streamModel.setPeerId(peerId);
        producerPresenter = new ProducerPresenter(this);
        eglBaseContext = EglBase.create().getEglBaseContext();
        videoCam = findViewById(R.id.videoCamImageView);
        videoCam.setOnClickListener(this);
        mic = findViewById(R.id.micImageView);
        mic.setOnClickListener(this);
        videoRecyclerView = findViewById(R.id.recycleView);
        videoRecyclerAdapter = new VideoRecyclerAdapter(getApplicationContext(), eglBaseContext);
        videoRecyclerView.setAdapter(videoRecyclerAdapter);

        GridLayoutManager gridLayoutManager = new GridLayoutManager(getApplicationContext(),2);
        videoRecyclerView.setLayoutManager(gridLayoutManager);


        // 初始化本地视频渲染控件，这个方法非常重要，不初始化会黑屏
         svrLocal = findViewById(R.id.local_video);
      //  remoteVideo = findViewById(R.id.remote_video);
        svrLocal.init(eglBaseContext, null);
//        mVideoTrack.addSink(svrLocal);
       // remoteVideo.init(eglBaseContext, null);

        // 创建 SurfaceTextureHelper 对象
        surfaceTextureHelper = SurfaceTextureHelper.create(
                "surfaceTextureHelperThread", eglBaseContext);
        this.requestController = new RequestController(getApplicationContext(), eglBaseContext, this, this, surfaceTextureHelper);

    }

    private void addLocalStreamModel(){
        runOnUiThread(new Runnable() {
            @Override
            public void run() {
                if (streamModel != null) {
                    List<StreamModel> streamModelList = videoRecyclerAdapter.getStreamModelList();
                    streamModelList = streamModelList.stream().filter(streamModel1 -> {
                        return !streamModel1.getPeerId().equals(peerId);
                    }).collect(Collectors.toList());
                    for (StreamModel streamModel1: streamModelList){
                        Log.e("stremModel", streamModel1.toString());
                    }
                    streamModelList.add(streamModel);
                    videoRecyclerAdapter.addVideoTracks(streamModelList);
                }
            }
        });

    }



    @Override
    public void callStream(HashMap<String, StreamModel> streamModelHashMap) {
        List<StreamModel> streamModelList = new ArrayList<>();
        Log.e(TAG, "callStream" + streamModelHashMap.size());
        for (Map.Entry<String, StreamModel> streamModelEntry: streamModelHashMap.entrySet()) {
            streamModelList.add(streamModelEntry.getValue());
        }
        streamModelList.add(this.streamModel);
        runOnUiThread(new Runnable() {
            @Override
            public void run() {
                Log.e(TAG, String.valueOf(streamModelList.size()));
                videoRecyclerAdapter.addVideoTracks(streamModelList);
            }
        });
    }

    @Override
    public void connectSuccess() {
        this.requestController.createTransport(true);
        this.requestController.createTransport(false);
    }

    @Override
    public void producer() {
        this.requestController.createProducer(true, true, this);
    }

    @Override
    public void onClick(View v) {
        switch (v.getId()){
            case R.id.videoCamImageView:
                producerPresenter.videoTrigger();
                break;
            case R.id.micImageView:
                producerPresenter.audioTrigger();
                break;
        }
    }

    @Override
    public void pauseProducer(String kind) {
        if (kind.equals("video")){
            this.videoCam.setImageResource(R.drawable.ic_baseline_videocam_off_24);
            this.requestController.pauseVideo();
            streamModel.setVPause(true);
            addLocalStreamModel();
        }
        if (kind.equals("audio")) {
            this.mic.setImageResource(R.drawable.ic_baseline_mic_off_24);
            this.requestController.pauseAudio();
            streamModel.setAPause(true);
            addLocalStreamModel();
        }
    }

    @Override
    public void resumeProducer(String kind) {
        if (kind.equals("video")){
            this.videoCam.setImageResource(R.drawable.ic_baseline_videocam_24);
            this.requestController.resumeVideo();
            streamModel.setVPause(false);
            addLocalStreamModel();
        } else {
            this.mic.setImageResource(R.drawable.ic_baseline_mic_24);
            this.requestController.resumeAudio();
            streamModel.setAPause(false);
            addLocalStreamModel();
        }
    }

    @Override
    public void videoTrack(VideoTrack videoTrack) {
        streamModel.setVideoTrack(videoTrack);
        streamModel.setVPause(false);
        addLocalStreamModel();
    }

    @Override
    public void audioTrack(AudioTrack audioTrack) {
        streamModel.setAudioTrack(audioTrack);
        streamModel.setAPause(false);
        addLocalStreamModel();
    }

    @Override
    protected void onDestroy() {
        super.onDestroy();
        this.requestController.release();
    }
}

